#!/usr/bin/env python2.7
# -*-encoding:utf8-*-

import math
import os
import setting
import sp_methods
import coordTransform_utils as trans_utils


def obtain_points(lon, lat):
    gcj = trans_utils.wgs84togcj02(float(lon), float(lat))
    bd = trans_utils.gcj02tobd09(gcj[0], gcj[1])
    return bd

def get_streetcodes():
    codes = setting.STREET_CODE
    z=0
    code_dict=dict()
    for i in setting.STREET:
        code_dict.setdefault(i,codes[z])
        z+=1
    return code_dict

def get_streets():
    streets = setting.STREET
    return streets


def count():
    sdict = dict()
    strWF = ''
    src = os.path.join(setting.DATA_DIR_PATH, setting.SRC_FILE_NAME)
    wrfile = os.path.join(setting.DATA_DIR_PATH, setting.SEC_SRC_FILE)

    wf = open(wrfile, 'w')
    with open(src, 'r') as sf:
        for line in sf:
            _, key = line.strip().split(',', 1)
            sdict.setdefault(key, set())
            sdict[key].add(_)
    for k in sdict.keys():
        w_eci, w_lon, w_lat, w_str, h_eci, h_lon, h_lat, h_str = k.split(',')
        conv_w_lon, conv_w_lat = obtain_points(float(w_lon), float(w_lat))
        conv_h_lon, conv_h_lat = obtain_points(float(h_lon), float(h_lat))
        _k = ','.join((w_eci, str(conv_w_lon), str(conv_w_lat), w_str, h_eci, str(conv_h_lon), str(conv_h_lat), h_str))
        strWF += _k + ',' + str(len(sdict[k])) + '\n'
    wf.write(strWF)
    wf.close()


def rad(x):
    """
    :param x: degree.
    :return:radium
    """
    return (x * math.pi) / 180.0


def distance(lat_1, long_1, lat_2, long_2):
    """
    Given two points on the earth, calculate the distance between them in meters.
    :param lat_1:
    :param long_1:
    :param lat_2:
    :param long_2:
    :return:distance in meters.
    """
    lat_1 = rad(lat_1)
    lat_2 = rad(lat_2)
    long_1 = rad(long_1)
    long_2 = rad(long_2)
    a = (lat_1 - lat_2) * 1.0 / 2
    b = (long_1 - long_2) * 1.0 / 2
    m = math.sin(a) ** 2 + math.cos(lat_1) * math.cos(lat_2) * math.sin(b) ** 2
    r = 6378137
    s = 2 * math.asin(math.sqrt(m)) * r
    return s


def max_distance(_street_name):
    max_dis = 0
    selected_dict = dict()
    src_file = os.path.join(setting.DATA_DIR_PATH, setting.SEC_SRC_FILE)
    with open(src_file, 'r') as rf:
        for line in rf:
            work_ci, wlon, wlat, wstreet, home_ci, hlon, hlat, hstreet, value = line.split(',')
            _k = ','.join([work_ci, wlon, wlat, wstreet, home_ci, hlon, hlat, hstreet])
            _v = value.strip()
            if setting.workOrhome == 'work':
                """set street here 1"""
                if wstreet == _street_name:
                    selected_dict.setdefault(_k, _v)
                    try:
                        current_dis = distance(float(hlat.strip()), float(hlon.strip()), float(wlat.strip()),
                                               float(wlon.strip()))
                    except:
                        print 'error:' + str(len(wlon.replace('\xc2\xa0', '').strip())), wlon, wlat, hlon, hlat
                    if current_dis > max_dis:
                        max_dis = current_dis
                        max_wlon = wlon
                        max_hlon = hlon
                        max_hlat = hlat
                        max_wlat = wlat
                        _value = value
            elif setting.workOrhome == 'home':
                """set street here 2"""
                if hstreet == _street_name:
                    selected_dict.setdefault(_k, _v)
                    try:
                        current_dis = distance( float(wlat.strip()),
                                               float(wlon.strip()),float(hlat.strip()), float(hlon.strip()))
                    except:
                        print 'error:' + str(len(wlon.replace('\xc2\xa0', '').strip())), wlon, wlat, hlon, hlat
                    if current_dis > max_dis:
                        max_dis = current_dis
                        max_wlon = wlon
                        max_hlon = hlon
                        max_hlat = hlat
                        max_wlat = wlat
                        _value = value
    n = math.ceil(max_dis / setting.SIDE)
    print max_wlon, max_wlat, max_hlon, max_hlat, _value
    return max_dis, n, selected_dict


if __name__ == '__main__':
    if setting.recalculalte_src:
        count()
    street_codes = get_streetcodes()
    print street_codes
    for _street in get_streets():
        max_dis, n, selected_dict = max_distance(_street)
        print max_dis, n

        all_list = list()
        for _key in selected_dict.keys():
            _work_ci, _wlon, _wlat, _wstreet, _home_ci, _hlon, _hlat, _hstreet = _key.split(',')
            current_distance = distance(float(_hlat), float(_hlon), float(_wlat), float(_wlon))
            m = math.ceil(current_distance / max_dis * n)
            #print '\n', m

            _list = list()
            if setting.workOrhome == 'work':
                if float(_wlat) != float(_hlat):
                    unit_lat = sp_methods.unit_degree(float(_wlat), float(_hlat), m)
                else:
                    unit_lat = 0
                if float(_wlon) != float(_hlon):
                    unit_lon = sp_methods.unit_degree(float(_wlon), float(_hlon), m)
                else:
                    unit_lon = 0
                #print(u"lon:{}\nlat:{}".format(unit_lon, unit_lat))
                lon_before = float(_wlon)  # y:longitude
                lat_before = float(_wlat)  # x:latitude
                """first append"""
                _list.append((lon_before, lat_before, int(selected_dict[_key])))
                for j in range(int(n)):
                    if unit_lat >= 0:
                        if lat_before < float(_hlat):
                            lat_before += unit_lat
                        else:
                            lat_before = float(_hlat)
                    else:
                        if lat_before > float(_hlat):
                            lat_before += float(unit_lat)
                        else:
                            lat_before = float(_hlat)
                    # longitude
                    if unit_lon >= 0:
                        if lon_before < float(_hlon):
                            lon_before += float(unit_lon)
                        else:
                            lon_before = float(_hlon)
                    else:
                        if lon_before > float(_hlon):
                            lon_before += float(unit_lon)
                        else:
                            lon_before = float(_hlon)
                    """second append"""
                    _list.append((lon_before, lat_before, int(selected_dict[_key])))

            elif setting.workOrhome == 'home':
                if float(_wlat) != float(_hlat):
                    unit_lat = sp_methods.unit_degree(float(_hlat),float(_wlat), m)
                else:
                    unit_lat = 0
                if float(_wlon) != float(_hlon):
                    unit_lon = sp_methods.unit_degree(float(_hlon),float(_wlon), m)
                else:
                    unit_lon = 0
                #print(u"lon:{}\nlat:{}".format(unit_lon, unit_lat))

                lon_before = float(_hlon)  # y:longitude
                lat_before = float(_hlat)  # x:latitude
                _list.append((lon_before, lat_before,int(selected_dict[_key])))
                for j in range(int(n)):
                    if unit_lat >= 0:
                        if lat_before < float(_wlat):
                            lat_before += unit_lat
                            if lat_before > float(_wlat):
                                lat_before = float(_wlat)
                        else:
                            lat_before = float(_wlat)
                    else:
                        if lat_before > float(_wlat):
                            lat_before += float(unit_lat)
                            if lat_before < float(_wlat):
                                lat_before = float(_wlat)
                        else:
                            lat_before = float(_wlat)
                    # longitude
                    if unit_lon >= 0:
                        if lon_before < float(_wlon):
                            lon_before += float(unit_lon)
                            if lon_before >  float(_wlon):
                                lon_before = float(_wlon)
                        else:
                            lon_before = float(_wlon)
                    else:
                        if lon_before > float(_wlon):
                            lon_before += float(unit_lon)
                            if lon_before < float(_wlon):
                                lon_before = float(_wlon)
                        else:
                            lon_before = float(_wlon)
                    """third append"""
                    _list.append((lon_before, lat_before, int(selected_dict[_key])))

            #print _list
            all_list.append(_list)

        """set street here 3"""
        wrpath_street = os.path.join(setting.RESULT_DATA_DIR_PATH,street_codes[_street])
        if not os.path.exists(wrpath_street):
            os.mkdir(wrpath_street)
        wrpath_query_type = os.path.join(wrpath_street, setting.workOrhome)
        if not os.path.exists(wrpath_query_type):
            os.mkdir(wrpath_query_type)

        print 'total file %d' % n
        for s in range(int(n)):
            str_to_write=''

            _l = list()
            for i in all_list:
                _l.append(str([x for x in i[s]]))
            str_to_write ='['+','.join(_l)+']'
            wrfile_name = os.path.join(wrpath_query_type,"{0:02d}".format(s+1))
            with open(wrfile_name,'w') as final_wf:
                final_wf.write(str_to_write)

